package com.lagou.edu.factory;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.utils.ClassUtils;
import com.lagou.edu.utils.StringUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author benwen
 * <p>
 * 工厂类，生产对象（使用注解技术）
 */
public class AnnotationBeanFactory {

    /**
     * 任务一：扫描basePackage，得到通过反射技术实例化对象并且存储待用（map集合）
     * 任务二：对外提供获取实例对象的接口（根据id获取）
     */

    private static final Map<String, Object> map = new HashMap<>();  // 存储对象

    static {

        Set<String> autowireSet = new HashSet<>();
        try {
            // 任务一
            List<Class<?>> classes = ClassUtils.getClasses("com.lagou.edu");

            for (Class<?> aClass : classes) {
                Service annotation = aClass.getAnnotation(Service.class);

                if (annotation != null) {

                    // 有Service 注解有value，则使用其配置，没有按照类名首字母小写
                    String name = annotation.value();
                    if (name == null || name.isEmpty()) {
                        name = StringUtils.toLowerCaseFirstOne(aClass.getSimpleName());
                        System.err.println("class: " + name);
                    }

                    Class<?> clazz = Class.forName(aClass.getName());
                    Object o = clazz.newInstance();  // 实例化之后的对象
                    // 存储到map中待用
                    map.put(name, o);

                    // 遍历所有字段
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        if (field.isAnnotationPresent(Autowired.class)) {
                            autowireSet.add(name);
                            break;
                        }
                    }
                }
            }

            // 处理需要 autowire 的字段
            for (String s : autowireSet) {
                System.err.println("---处理bean中的autowire---: " + s);
                Object o = map.get(s);
                Field[] fields = o.getClass().getDeclaredFields();
                for (Field field : fields) {
                    Autowired autowired = field.getAnnotation(Autowired.class);
                    if (autowired != null) {
                        String fieldName = autowired.value();
                        if (fieldName == null || fieldName.isEmpty()) {
                            fieldName = StringUtils.toLowerCaseFirstOne(field.getName());
                            System.err.println("    filedName:" + fieldName);
                        }
                        field.setAccessible(true);
                        System.err.println("map: " + map.get(fieldName));
                        field.set(o, map.get(fieldName));
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    // 任务二：对外提供获取实例对象的接口（根据id获取）
    public static Object getBean(String id) {
        return map.get(id);
    }

}
